package lumis.content.source.field.type;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import lumis.content.core.ContentTag;
import lumis.doui.render.IRenderable;
import lumis.doui.render.IRenderer;
import lumis.doui.source.field.type.AbstractSourceFieldDataType;
import lumis.portal.PortalException;
import lumis.portal.authentication.SessionConfig;
import lumis.util.XmlUtil;
import lumis.util.query.QueryFieldTypes;

/**
 * Tag data type.
 * 
 *
 * @version $Revision: 13092 $ $Date: 2011-05-28 18:19:06 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
public class TagDataType extends AbstractSourceFieldDataType
{
	
	/**
	 * Data object for a field with data type tag.
	 * @since 6.0.0
	 */
	public static class Data implements IRenderable
	{
		public static class Tag
		{
			private String name;
			
			public void setName(String name)
			{
				this.name = name;
			}
			
			public String getName()
			{
				return name;
			}
		}
		
		private List<Tag> tags;
		
		/**
		 * {@link Data} constructor.
		 * @param tags, Collection of Tags.
		 * @see Tag 
		 * @since 6.0.0
		 */
		@SuppressWarnings("unchecked")
		public Data(Collection<Tag> tags)
		{
			super();
			
			this.tags = new ArrayList<Tag>(tags);
			
			// Order tags
			Collections.<Tag>sort(this.tags, new Comparator<Tag>() {
				public int compare(Tag tag1, Tag tag2) 
				{
					Collator collator = Collator.getInstance(SessionConfig.getCurrentSessionConfig().getLocale());
					return collator.compare(tag1.getName(), tag2.getName());
				}
			});
		}

		/**
		 * Returns the list of tags ordered by name. 
		 * 
		 * @return the list of tags ordered by name.
		 * @since 6.0.0
		 */
		public List<Tag> getTags()
		{
			return this.tags;
		}

		/**
		 * @since 6.0.0
		 */
		public String getRenderData(IRenderer renderer) throws PortalException
		{
			StringBuilder value = new StringBuilder(tags.size() * 60);
			value.append("<tags>");
			
			for(Tag Tag:tags)
			{
				value.append("<tag>");
				value.append("<name>" + XmlUtil.encodeXml(Tag.getName()) + "</name>");
				value.append("</tag>");
			}
			value.append("</tags>");
			
			return value.toString();
		}

		/**
		 * @since 6.0.0
		 */
		public String getDisplayString(IRenderer renderer) throws PortalException
		{
			StringBuilder displaySB = new StringBuilder(tags.size() * 20); 
			for (Iterator iterator = tags.iterator(); iterator.hasNext();) 
			{
				Tag tag = (Tag) iterator.next();
				displaySB.append(tag.getName());
				if(iterator.hasNext())
					displaySB.append(ContentTag.TAG_STRING_SEPARATOR+" ");
			}
			
			return displaySB.toString();
		}
	}
	
	/**
	 * @since 6.0.0
	 */
	@Override
	public String getId()
	{
		return TagDataType.class.getName();
	}
	
	/**
	 * @since 6.0.0
	 */
	@Override
	public String getQueryDataType()
	{
		return QueryFieldTypes.GUID;
	}

	/**
	 * @since 6.0.0
	 */
	@Override
	public Class<? extends Data> getValueClass()
	{
		return Data.class;
	}

	/**
	 * @since 6.0.0
	 */
	@Override
	public String getDefaultInputControlType()
	{
		return "lum_inputTag";
	}
}
